﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGinnBPM.Services;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
using NLog;
using NGinnBPM.Services.Utilities;

namespace NGinnBPM.Dao
{
    public class RawSqlMessageCorrelationIdResolver : IMessageCorrelationIdResolver
    {
        private Logger log = LogManager.GetCurrentClassLogger();

        public ITaskDatabaseSessionFactory SessionFactory { get; set; }

       

        private void AccessDb(Action<IDbConnection> act)
        {
            var ses = TaskDatabaseSession.CurrentSession;
            if (ses != null)
            {
                act((IDbConnection)ses.Connection);
            }
            else
            {
                using (ITaskDatabaseSession ses2 = SessionFactory.OpenSession())
                {
                    act((IDbConnection)ses.Connection);
                }
            }
        }

        #region ITaskCorrelationIdResolver Members

        public void RegisterMapping(string id, string taskCorrelationId)
        {
            AccessDb(delegate(IDbConnection conn)
            {
                using (IDbCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "select message_id from MessageCorrelationMapping where message_id=@message_id and instance_id=@instance_id";
                    SqlDBUtil.AddParameter(cmd, "@message_id", id);
                    SqlDBUtil.AddParameter(cmd, "@instance_id", taskCorrelationId);
                    using (IDataReader dr = cmd.ExecuteReader())
                    {
                        if (dr.Read())
                        {
                            log.Warn("Message mapping already registered: {0}->{1}", id, taskCorrelationId);
                            return;
                        }
                    }
                    cmd.CommandText = "insert into MessageCorrelationMapping(message_id, instance_id, insert_date) " +
                        "values (@message_id, @instance_id, getdate())";
                    //NGinnBPM.Services.Utilities.SqlDBUtil.AddParameter(cmd, "@message_id", id);
                    //NGinnBPM.Services.Utilities.SqlDBUtil.AddParameter(cmd, "@instance_id", taskCorrelationId);
                    cmd.ExecuteNonQuery();
                }
            });
        }

        public string GetReceiveTaskInstanceId(string id)
        {
            string ret = null;
            AccessDb(delegate(IDbConnection con)
            {
                using (IDbCommand cmd = con.CreateCommand())
                {
                    cmd.CommandText = "select instance_id from MessageCorrelationMapping where message_id=@message_id";
                    SqlDBUtil.AddParameter(cmd, "@message_id", id);
                    using (IDataReader dr = cmd.ExecuteReader())
                    {
                        if (!dr.Read())
                        {
                            log.Info("Message mapping not found: {0}", id);
                            return;
                        }
                        ret = dr.GetString(0);
                        return ;
                    }
                }
            });
            return ret;
        }

        public void RemoveMapping(string id, string taskCorrelationId)
        {
            AccessDb(delegate(IDbConnection con)
            {
                using (IDbCommand cmd = con.CreateCommand())
                {
                    cmd.CommandText = "delete MessageCorrelationMapping where message_id=@message_id and instance_id=@instance_id";
                    SqlDBUtil.AddParameter(cmd, "@message_id", id);
                    SqlDBUtil.AddParameter(cmd, "@instance_id", taskCorrelationId);
                    cmd.ExecuteNonQuery();
                }
            });
        }

        public void RemoveAllProcessMappings(string processInstanceId)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
